// Log Manager realization
// (c) jimon game studio

#include "CLogManager.h"
#include "ITimer.h"
#include "jeThreads.h"

#include <stdio.h>
#include <time.h>

namespace je
{
	namespace core
	{
		IMPLEMENT_SINGLETON(LogManager,JE_ENGINE_FUNCTION_CALL)

		//! Constructor
		CLogManager::CLogManager()
			:OutFile(NULL),LogFunction(NULL)
		{
			SetLogManager(this);

			#ifdef JE_LOG_TOFILE
			JENEW(OutFile,std::ofstream(JE_LOG_FILE))

			time_t rawtime;
			struct tm timeinfo;

			time(&rawtime);
			#ifdef JE_MSVC
			localtime_s(&timeinfo,&rawtime);
			#else
			timeinfo = *localtime(&rawtime);
			#endif

			#ifdef JE_MSVC
			c8 * Buffer;
			JENEW_A(Buffer,c8,sizeof(tm)+256)
			asctime_s(Buffer,sizeof(tm)+256,&timeinfo);
			#else
			c8 * Buffer = asctime(&timeinfo);
			#endif

			(*OutFile) << "Log Started at " << Buffer;
			(*OutFile) << "-------------------------------" << std::endl;

			OutFile->flush();

			#ifdef JE_MSVC
			JEDELETE_A(Buffer)
			#endif
			#endif
		}

		//! Destructor
		CLogManager::~CLogManager()
		{
			#ifdef JE_LOG_TOFILE
			(*OutFile) << "-------------------------------" << std::endl;
			(*OutFile) << "Log Closed" << std::endl;

			OutFile->flush();

			OutFile->close();
			JEDELETE(OutFile)
			OutFile = NULL;
			#endif

			SetLogManager(NULL);
		}

		//! Add String to log
		void CLogManager::AddLog(const jeStringc & Log,LogMessageLevels WarningLevel)
		{
			f64 Time = GetTimer()->GetTime();

			jeStringc out;

			switch(WarningLevel)
			{
			case LML_WARNING:
				out += "! Warning ! ";
				break;
			case LML_ERROR:
				out += "! Error ! ";
				break;
			default:
				break;
			}

			if(LogFunction)
				LogFunction(out+Log,WarningLevel);

			out += (int)Time;
			out += ">";
			out += Log;
			out += "\n";

			#ifdef JE_LOG_TOFILE
			OutFile->write(out.c_str(),out.GetSize());
			OutFile->flush();
			#endif

			#ifdef JE_LOG_TOCONSOLE
			printf("%s",out.c_str());
			#endif
		}

		//! Set Log Callback
		void CLogManager::SetLogCallback(const jeLogFunction & Callback)
		{
			LogFunction = Callback;
		}
	}
}

